#pragma once
class StateEvent;
class IStateReceiver
{
public:
	virtual bool DoStateEvent(std::shared_ptr<StateEvent> event) = 0;
	virtual bool NotifyMaker(std::shared_ptr<StateEvent> event);
};

class IStateMaker
{
public:
	virtual bool MakeStateEvent(std::shared_ptr<StateEvent> event) = 0;
	virtual bool NotifyReceiver(std::shared_ptr<StateEvent> event);
};

//enum StateEventType {
//	StateEventType_None = 0,
//	StateEventType_ToMaker,
//	StateEventType_ToReceiver,
//};
enum StateEventValue {
	StateEvent_None = 0,
	StateEvent_InsertControl,
	StateEvent_InsertBox,
	StateEvent_Selected,
	StateEvent_ResetRoot,
	StateEvent_MouseEnter,
};

class StateEvent 
{
public:
	ui::Control* p{ nullptr };
	ui::Box* parent{ nullptr };
	IStateReceiver* from{ nullptr };
	IStateMaker* maker{ nullptr };
	//StateEventType et{ StateEventType_None };
	StateEventValue ev{ StateEvent_None };
	std::string id;
};


class StateMachine
{
	friend class IStateReceiver;
	friend class IStateMaker;
public:
	StateMachine() {};
	~StateMachine() {};

	bool InsertReceiver(IStateReceiver* receiver);
	bool InsertMaker(IStateMaker* maker);
private:
	
	bool NotifyReceiver(std::shared_ptr<StateEvent> event);
	bool NotifyMaker(std::shared_ptr<StateEvent> event);

	bool Rollback();
	bool RollTo(int version);
	
private:
	std::vector<IStateReceiver*> m_vecAcceptor;
	IStateMaker* m_coreMaker{ nullptr };

	std::vector<std::shared_ptr<StateEvent>> m_vecHistoryEvent;
	int m_currVersion{ -1 };
};

extern StateMachine* gStateMachine;

